package com.foton.logistic.util;

import android.content.Context;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.foton.logistic.base.BaseApplication;
import com.foton.logistic.model.GPSEntity;
import com.foton.logistic.util.tool.LogUtil;

import java.util.regex.Pattern;

import permissions.dispatcher.PermissionUtils;

public class LocationUtil {
    private static LocationUtil locationUtil;
    Context  context;

    protected int locTime = 600000;//定位周期
    public BDAbstractLocationListener myListener;//定位监听？
    public LocationClient mLocClient;
    private LocationClientOption locationClientOption;

    //GCJ02 转 GPS84相关参数
    public static double pi = 3.1415926535897932384626;
    public static double a = 6378245.0;
    public static double ee = 0.00669342162296594323;

//    public static synchronized LocationUtil getInstance(Context paramContext, BaseApplication.MyLocationListenner myListener) {
//        if (locationUtil == null)
//            locationUtil = new LocationUtil(paramContext,myListener);
//        LocationUtil local = locationUtil;
//        return local;
//    }

    public LocationUtil(Context context, BDAbstractLocationListener myListener) {
        this.context = context;
        this.myListener = myListener;
        init();
    }

    public static LocationUtil getInstance(){
        return locationUtil;
    }

    void init(){
        locationUtil = this;
        if (BaseApplication.self().mLocClient==null){
            BaseApplication.self().mLocClient = new LocationClient(BaseApplication.self());
        }
        mLocClient = BaseApplication.self().mLocClient;
        mLocClient.registerLocationListener(myListener);
        locationClientOption = new LocationClientOption();
        setLocationOption(""+locTime);
        //TODO 检查定位监听逻辑
    }

    /**
     * 获取定位
     */
    public int location(String time){
        //没有定位权限不启动定位
        if (!PermissionUtils.hasSelfPermissions(BaseApplication.self(), PermissionUtil.CHECK_LOCTION_PERMISSION_NAME)){
            return 0;
        }
        int res = 0;
        try {
            if(mLocClient!=null){
                setLocationOption(time);
                if(!mLocClient.isStarted()){
                    //mLocClient.start();
                    mLocClient.restart();
//                    OptionUtil.addToast(context, context.getString(R.string.track_bd_loc_success));
//                    new Handler().postDelayed(new Runnable(){
//                        public void run() {
//                            int res = mLocClient.requestLocation();
//                            if (res==0){
//                                //启动定位成功
//                                OptionUtil.addToast(context, context.getString(R.string.track_bd_loc_success));
//                            }else {
//                                OptionUtil.addToast(context, context.getString(R.string.track_bd_loc_fail));
//                            }
//                        }
//                    }, 1500);

                }else {
                    res = mLocClient.requestLocation();
                    if(res==6){
                        res = 0;
                    }
                }
            }else {
                LogUtil.e("baidu locClient is null or not started");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return res;
    }

    public void stopLocation(){
        try {
            mLocClient.stop();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public int keepLocation(String time){
        int res = 0;
        if (!PermissionUtils.hasSelfPermissions(BaseApplication.self(), PermissionUtil.CHECK_LOCTION_PERMISSION_NAME)){
            return 0;
        }
        try {
            if(mLocClient!=null){
                setLocationOption(time);
                LogUtil.e("---------mLocClient.isStarted()="+mLocClient.isStarted());
                if(!mLocClient.isStarted()){
                    mLocClient.start();
                }else {

                }
            }else {
                LogUtil.e("baidu locClient is null or not started");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return res;
    }

//    public void relocation(int time){
////        stopLocation();
//        location(""+time);
//    }

    /**
     * 定位设置相关参数
     * @param time
     */
    public void setLocationOption(String time){
        locationClientOption.setOpenGps(true); // 打开gps
        locationClientOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        locationClientOption.setCoorType("gcj02"); // 设置坐标类型gcj02
//		locationClientOption.setIsNeedAddress(false);//可选，设置是否需要地址信息，默认不需要
//		locationClientOption.setIsNeedLocationDescribe(false);//可选，设置是否需要地址描述
//		locationClientOption.setNeedDeviceDirect(false);//可选，设置是否需要设备方向结果
//		locationClientOption.setLocationNotify(false);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
//		locationClientOption.setIgnoreKillProcess(false);//可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
//		locationClientOption.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
//		locationClientOption.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
//		locationClientOption.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        if(null!=time)
        {
            boolean b = isNumeric(time);
            if(b)
            {
                locationClientOption.setScanSpan(Integer.parseInt(time));	//设置定位模式，小于1秒则一次定位;大于等于1秒则定时定位
            }
        }
        locationClientOption.setAddrType("all");
        locationClientOption.disableCache(true);
//        locationClientOption.setIgnoreKillProcess(false);
        mLocClient.setLocOption(locationClientOption);
    }

    protected boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /*
     * gcj02转换gps84相关方法
     */

    public static boolean outOfChina(double lat, double lon) {
        if (lon < 72.004 || lon > 137.8347)
            return true;
        if (lat < 0.8293 || lat > 55.8271)
            return true;
        return false;
    }

    public static GPSEntity gcj_To_Gps84(double lat,double lon){
        GPSEntity gps = transform(lat, lon);
        double lontitude = lon * 2 - gps.getWgLon();
        double latitude = lat * 2 - gps.getWgLat();
        return new GPSEntity(latitude, lontitude);
    }

    public static GPSEntity transform(double lat, double lon) {
        if (outOfChina(lat, lon)) {
            return new GPSEntity(lat, lon);
        }
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        return new GPSEntity(mgLat, mgLon);
    }

    public static double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y
                + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    public static double transformLon(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
                * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
                * pi)) * 2.0 / 3.0;
        return ret;
    }


}